import datetime
import requests

class Request(object):

    def __init__(self, url, session=False, **kwargs):
        '''
        :param url:
        :param session:    是否以session的方式请求
        :param kwargs:  kwargs涵盖了requests原生的参数，只要你想传，你都可以传进来。
        '''
        self.url = url
        self.session = session
        self.kwargs = kwargs

        if self.session:
            self.client = requests.session()
        else:
            self.client = requests


    @staticmethod
    def get_elapsed(timer: datetime.timedelta):
        '''
        get_elapsed是根据postman为参照，对请求时间做的一个处理，
        如果大于1s的请求响应时间，那我们以秒为单位显示，否则以毫秒为单位显示。
        :param timer: 请求响应的时间
        :return:
        '''
        if timer.seconds > 0:
            return f"{timer.seconds}.{timer.microseconds // 1000}s"
        return f"{timer.microseconds // 100}ms"


    def request(self, method: str):
        '''
        request封装了requests库的核心操作，基本上属于原生处理，并且判断了http状态码。
        :param method: 请求方法
        :return:
        '''
        status_code = 0
        elapsed = "-1ms"
        try:
            if method.upper() == "GET":
                response = self.client.get(self.url, **self.kwargs, timeout=300)
            elif method.upper() == 'POST':
                response = self.client.post(self.url, **self.kwargs, timeout=300)
            else:
                response = self.client.request(method, self.url, **self.kwargs, timeout=300)

            status_code = response.status_code
            # 如果响应状态吗不为200，则直接返回response
            if status_code != 200:
                return Request.response(False, status_code)

            elapsed = Request.get_elapsed(response.elapsed)

            data = self.get_response(response)

            print(f"response.request.headers == > {response.request.headers}")

            print(type(response.request.headers))

            return Request.response(True, 200, data, response.headers, response.request.headers, elapsed=elapsed, cookies=response.cookies)

        except Exception as e:
            return Request.response(False, status_code, msg=str(e), elapsed=elapsed)

    # response是构造返回结构对象，对本次请求的数据进行整理。
    @staticmethod
    def response(status, status_code=200, response=None, response_header=None,
                 request_header=None, cookies=None, elapsed=None, msg="success"):
        '''
        response是构造返回结构对象，对本次请求的数据进行整理。
        :param status: 请求结果的状态
        :param status_code: 状态码
        :param response: 响应体
        :param response_header: 响应头
        :param request_header:  请求头
        :param elapsed: 执行时间
        :param msg: 在DAO层的http 调用request后传递
        :return:
        '''
        # 接收到的response.headers  不是一个普通的字典，而是一个类字典的数据！！！
        # 如果没有headers则直接返回{}而不去遍历headers了。
        request_header = {k: v for k, v in request_header.items()} if request_header is not None else {}
        # request_header =request_header if request_header is not None else {}

        response_header = {k: v for k, v in response_header.items()} if response_header is not None else {}
        cookies = {k:v for k,v in cookies.items()} if cookies is not None else {}

        return {
            "status": status, "response": response, "status_code": status_code,
            "response_header": response_header, "request_header": request_header,
            "msg": msg, "elapsed": elapsed, "cookies":cookies
        }

    # 把响应内容拿出来
    def get_response(self,response):
        try:
            return response.json()
        except:
            return response.text

    def get(self):
        return self.request("GET")

    def post(self):
        return self.request("POST")
